package cn.threewaters.qtyy.config.multids;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;

import cn.threewaters.qtyy.config.shiro.ShiroManager;
import cn.threewaters.qtyy.dit.one.entity.base.OneBaseModel;
import cn.threewaters.qtyy.util.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

@Component
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
@Slf4j
public class FillPublicColumnInterceptor implements Interceptor {
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
		SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
		Object parameter = invocation.getArgs()[1];
		List<Field> fields = Lists.newArrayList();
		Class<? extends Object> tempClass = parameter.getClass();
		while (tempClass != null) {
			fields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
			tempClass = tempClass.getSuperclass();
		}
		log.debug(parameter.getClass().getName());
		// TODO:此处可扩展，对应不同包下的实体，去填充不同的字段
		if (SqlCommandType.INSERT == sqlCommandType) {
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.getName().equals("activeFlag") && ObjectUtil.isNull(field.get(parameter))) {
					field.set(parameter, OneBaseModel.ACTIVE_FLAG_YES);
				}
				if (field.getName().equals("createBy") && ObjectUtil.isNull(field.get(parameter))) {
					field.set(parameter, ShiroManager.getUserInfo().getRealname());
				}
				if (field.getName().equals("createDate") && ObjectUtil.isNull(field.get(parameter))) {
					field.set(parameter, new Date());
				}
				field.setAccessible(false);
			}
		}
		if (SqlCommandType.UPDATE == sqlCommandType) {
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.getName().equals("updateBy") && ObjectUtil.isNull(field.get(parameter))) {
					field.set(parameter, ShiroManager.getUserInfo().getRealname());
				}
				if (field.getName().equals("updateDate") && ObjectUtil.isNull(field.get(parameter))) {
					field.set(parameter, new Date());
				}
				field.setAccessible(false);
			}
		}
		return invocation.proceed();
	}

	@Override
	public Object plugin(Object target) {
		if (target instanceof Executor) {
			return Plugin.wrap(target, this);
		} else {
			return target;
		}
	}

	@Override
	public void setProperties(Properties properties) {

	}

}
